package cj.primariaiquest.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;

import cj.primariaiquest.dao.exceptions.DaoException;

/**
 * Base class used for entity managers. Uses generics to perform CRUD
 * operations.
 * 
 * @author georgian.parvu
 * 
 */
public abstract class BaseEntityManager<T> {
    private static final EntityManagerFactory emf;

    private EntityManager em = emf.createEntityManager();

    static {
	emf = Persistence
		.createEntityManagerFactory("$objectdb/db/tickets.odb");
    }

    protected static EntityManagerFactory getEmf() {
	return emf;
    }

    protected EntityManager getEm() {
	return em;
    }

    /**
     * Stores a object to database
     * 
     * @param obj
     *            obj to be stored
     * @throws DaoException
     */
    protected synchronized void persist(final T obj) throws Exception {
	em.getTransaction().begin();
	em.persist(obj);
	em.getTransaction().commit();
    }

    /**
     * Returns a List< T > off all object from database.
     * 
     * @return List< T >
     */
    protected synchronized List<T> getAllObjects(final Class<T> cls)
	    throws Exception {
	TypedQuery<T> query = (TypedQuery<T>) em.createQuery("SELECT o FROM "
		+ cls.getSimpleName() + " o", cls);
	return query.getResultList();
    }

    /**
     * Deletes the provided object from database.
     * 
     * @param obj
     *            object to be deleted
     */
    protected synchronized void deleteObject(final T obj) throws Exception {
	em.getTransaction().begin();
	em.remove(obj);
	em.getTransaction().commit();
    }

    /**
     * Deletes all objects from database
     */
    protected synchronized void deleteAllObjects(final Class<T> cls)
	    throws Exception {
	for (T obj : getAllObjects(cls)) {
	    deleteObject(obj);
	}
    }
}
